#include <os/task.h>
#include <freertos/include/FreeRTOS.h>
#include <freertos/include/task.h>


/**
 * @brief dynamatic create a task
 * @param task_func task function
 * @param name task name
 * @param stack_size stack size
 * @param arg task argument
 * @param priority task priority
 * @return task handle
 */
task_t task_create(task_func_t task_func, const char *name, int stack_size, void *arg, int priority)
{
    task_t handle = NULL;
    xTaskCreate(task_func, name, stack_size, arg, priority, (TaskHandle_t*)&handle);
    return handle;
}


/**
 * @brief dynamatic create a task
 * @param task_func task function
 * @param name task name
 * @param stack task stack
 * @param stack_size stack size
 * @param arg task argument
 * @param priority task priority
 * @return task handle
 */
task_t task_create_static(task_func_t task_func, const char *name, void *stack, int stack_size, void *arg, int priority)
{
    task_t handle = NULL;
    handle = (task_t)xTaskCreateStatic(task_func, name, stack_size, arg, priority, stack, (StaticTask_t*)stack);
    return handle;
}


/**
 * @brief delete a task
 * @param handle task handle
 * @return none
 */
void task_delete(task_t handle)
{
    vTaskDelete(handle);
}


/**
 * @brief start scheduler
 * @param none
 * @return none
 * @note this function will not return
 */
void task_start_scheduler(void)
{
    vTaskStartScheduler();
}


/**
 * @brief delay a task
 * @param milliseconds delay time
 * @return none
 */
void task_delay(int ms)
{
    vTaskDelay(pdMS_TO_TICKS(ms));
}


/**
 * @brief enter critical section
 * @param none
 * @return none
 * @note for freertos, this function will turn off interrupt
 */
void enter_critical(void)
{
    taskENTER_CRITICAL();
}


/**
 * @brief exit critical section
 * @param none
 * @return none
 * @note for freertos, this function will turn on interrupt
 */
void exit_critical(void)
{
    taskEXIT_CRITICAL();
}
